refs: resolve conflict between local/remote repos
authorYu Qi Zhang <jzehrarnyg@gmail.com>
Thu, 23 Jun 2016 16:11:50 +0000 (16:11 +0000)
committerAtomic Bot <atomic-devel@projectatomic.io>
Thu, 23 Jun 2016 19:52:26 +0000 (19:52 +0000)
Add the functionality to use the same name for refs in local and remote
repos. This helps users keep track of local refs of remote origin, much
like local and remote git branches.

Previously, when a local ref is specified, resolve_refspec would fall
back to searching through remote repos if the ref is not found locally.
This function now takes an extra flag to specify whether it should
search through remote repos. Additionally, ostree_repo_resove_rev_ext
was added to call resolve_refspec with fallback_remote being false, so
refs --create would no longer complain when trying to create a local
ref of the same name as a remote one.

Fix remote repo parsing not being handled correctly on refs --create.

Closes: #363
Approved by: jlebon

apidoc/ostree-sections.txt
src/libostree/libostree.sym
src/libostree/ostree-repo-refs.c
src/libostree/ostree-repo.h
src/ostree/ot-builtin-refs.c
tests/test-refs.sh

index 6dca9ecc9ca9b6e7f5d9a68987d1b964dfe9f6d2..cc77f15a4be75fae059a7387f0626a4d922aabd2 100644 (file)
@@ -300,6 +300,7 @@ ostree_repo_write_content_trusted
 ostree_repo_write_content_async
 ostree_repo_write_content_finish
 ostree_repo_resolve_rev
+ostree_repo_resolve_rev_ext
 ostree_repo_list_refs
 ostree_repo_list_refs_ext
 ostree_repo_remote_list_refs
index 087f987926427a1e897457dcfa8e29afacbd4ebf..bdfa7c3fc6d6c2f53b0e4aeb857d970745111943 100644 (file)
@@ -346,10 +346,7 @@ global:
  *                         NOTE NOTE NOTE
  */
 
-/* Uncomment this when adding a new symbol */
-/*
 LIBOSTREE_2016.7 {
 global:
-        someostree_some_new_symbol;
+        ostree_repo_resolve_rev_ext;
 } LIBOSTREE_2016.6;
-*/
index b18d838e013ed3eb25cd43c14ee3deaf3a6e565b..18308d0cac9694aec5f195c4b89bf5a7c144e70e 100644 (file)
@@ -199,6 +199,7 @@ resolve_refspec (OstreeRepo     *self,
                  const char     *remote,
                  const char     *ref,
                  gboolean        allow_noent,
+                 gboolean        fallback_remote,
                  char          **out_rev,
                  GError        **error);
 
@@ -207,6 +208,7 @@ resolve_refspec_fallback (OstreeRepo     *self,
                           const char     *remote,
                           const char     *ref,
                           gboolean        allow_noent,
+                          gboolean        fallback_remote,
                           char          **out_rev,
                           GCancellable   *cancellable,
                           GError        **error)
@@ -216,8 +218,8 @@ resolve_refspec_fallback (OstreeRepo     *self,
 
   if (self->parent_repo)
     {
-      if (!resolve_refspec (self->parent_repo, remote, ref,
-                            allow_noent, &ret_rev, error))
+      if (!resolve_refspec (self->parent_repo, remote, ref, allow_noent,
+                            fallback_remote, &ret_rev, error))
         goto out;
     }
   else if (!allow_noent)
@@ -241,6 +243,7 @@ resolve_refspec (OstreeRepo     *self,
                  const char     *remote,
                  const char     *ref,
                  gboolean        allow_noent,
+                 gboolean        fallback_remote,
                  char          **out_rev,
                  GError        **error)
 {
@@ -270,7 +273,7 @@ resolve_refspec (OstreeRepo     *self,
       if (!ot_openat_ignore_enoent (self->repo_dir_fd, local_ref, &target_fd, error))
         goto out;
 
-      if (target_fd == -1)
+      if (target_fd == -1 && fallback_remote)
         {
           local_ref = glnx_strjoina ("refs/remotes/", ref);
 
@@ -300,7 +303,7 @@ resolve_refspec (OstreeRepo     *self,
     }
   else
     {
-      if (!resolve_refspec_fallback (self, remote, ref, allow_noent,
+      if (!resolve_refspec_fallback (self, remote, ref, allow_noent, fallback_remote,
                                      &ret_rev, cancellable, error))
         goto out;
     }
@@ -388,23 +391,13 @@ ostree_repo_resolve_partial_checksum (OstreeRepo   *self,
   return ret;
 }
 
-/**
- * ostree_repo_resolve_rev:
- * @self: Repo
- * @refspec: A refspec
- * @allow_noent: Do not throw an error if refspec does not exist
- * @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist
- * @error: Error
- *
- * Look up the given refspec, returning the checksum it references in
- * the parameter @out_rev.
- */
-gboolean
-ostree_repo_resolve_rev (OstreeRepo     *self,
-                         const char     *refspec,
-                         gboolean        allow_noent,
-                         char          **out_rev,
-                         GError        **error)
+static gboolean
+_ostree_repo_resolve_rev_internal (OstreeRepo     *self,
+                                   const char     *refspec,
+                                   gboolean        allow_noent,
+                                   gboolean        fallback_remote,
+                                   char          **out_rev,
+                                   GError        **error)
 {
   gboolean ret = FALSE;
   g_autofree char *ret_rev = NULL;
@@ -456,7 +449,7 @@ ostree_repo_resolve_rev (OstreeRepo     *self,
             goto out;
           
           if (!resolve_refspec (self, remote, ref, allow_noent,
-                                &ret_rev, error))
+                                fallback_remote, &ret_rev, error))
             goto out;
         }
     }
@@ -467,6 +460,53 @@ ostree_repo_resolve_rev (OstreeRepo     *self,
   return ret;
 }
 
+/**
+ * ostree_repo_resolve_rev:
+ * @self: Repo
+ * @refspec: A refspec
+ * @allow_noent: Do not throw an error if refspec does not exist
+ * @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist
+ * @error: Error
+ *
+ * Look up the given refspec, returning the checksum it references in
+ * the parameter @out_rev. Will fall back on remote directory if cannot
+ * find the given refspec in local.
+ */
+gboolean
+ostree_repo_resolve_rev (OstreeRepo     *self,
+                         const char     *refspec,
+                         gboolean        allow_noent,
+                         char          **out_rev,
+                         GError        **error)
+{
+  return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, TRUE, out_rev, error);
+}
+
+/**
+ * ostree_repo_resolve_rev_ext:
+ * @self: Repo
+ * @refspec: A refspec
+ * @allow_noent: Do not throw an error if refspec does not exist
+ * @flags: Options controlling behavior
+ * @out_rev: (out) (transfer full): A checksum,or %NULL if @allow_noent is true and it does not exist
+ * @error: Error
+ *
+ * Look up the given refspec, returning the checksum it references in
+ * the parameter @out_rev. Differently from ostree_repo_resolve_rev(),
+ * this will not fall back to searching through remote repos if a
+ * local ref is specified but not found.
+ */
+gboolean
+ostree_repo_resolve_rev_ext (OstreeRepo                    *self,
+                             const char                    *refspec,
+                             gboolean                       allow_noent,
+                             OstreeRepoResolveRevExtFlags   flags,
+                             char                         **out_rev,
+                             GError                       **error)
+{
+  return _ostree_repo_resolve_rev_internal (self, refspec, allow_noent, FALSE, out_rev, error);
+}
+
 static gboolean
 enumerate_refs_recurse (OstreeRepo    *repo,
                         const char    *remote,
index c023b4d284a59544f746bd49e9dbbf79915bcde5..2f60e633d43fa79d3001bf6405c429ddba93760a 100644 (file)
@@ -382,6 +382,22 @@ gboolean      ostree_repo_resolve_rev (OstreeRepo  *self,
                                        char       **out_rev,
                                        GError     **error);
 
+/**
+ * OstreeRepoResolveRevExtFlags:
+ * @OSTREE_REPO_RESOLVE_REV_EXT_NONE: No flags.
+ */
+typedef enum {
+  OSTREE_REPO_RESOLVE_REV_EXT_NONE = 0,
+} OstreeRepoResolveRevExtFlags;
+
+_OSTREE_PUBLIC
+gboolean      ostree_repo_resolve_rev_ext (OstreeRepo                    *self,
+                                           const char                    *refspec,
+                                           gboolean                       allow_noent,
+                                           OstreeRepoResolveRevExtFlags   flags,
+                                           char                         **out_rev,
+                                           GError                       **error);
+
 _OSTREE_PUBLIC
 gboolean      ostree_repo_list_refs (OstreeRepo       *self,
                                      const char       *refspec_prefix,
index fbdaf1bca57f85a22d575134412f0421576c7c9b..017b0c74b37f46cc259a3b32ae4ee4bf865ad735 100644 (file)
@@ -72,8 +72,10 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab
     {
       g_autofree char *checksum = NULL;
       g_autofree char *checksum_existing = NULL;
+      g_autofree char *remote = NULL;
+      g_autofree char *ref = NULL;
 
-      if (!ostree_repo_resolve_rev (repo, opt_create, TRUE, &checksum_existing, error))
+      if (!ostree_repo_resolve_rev_ext (repo, opt_create, TRUE, OSTREE_REPO_RESOLVE_REV_EXT_NONE, &checksum_existing, error))
         {
           if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY))
             {
@@ -94,7 +96,10 @@ static gboolean do_ref (OstreeRepo *repo, const char *refspec_prefix, GCancellab
       if (!ostree_repo_resolve_rev (repo, refspec_prefix, FALSE, &checksum, error))
         goto out;
 
-      if (!ostree_repo_set_ref_immediate (repo, NULL, opt_create, checksum,
+      if (!ostree_parse_refspec (opt_create, &remote, &ref, error))
+        goto out;
+
+      if (!ostree_repo_set_ref_immediate (repo, remote, ref, checksum,
                                           cancellable, error))
         goto out;
     }
index 310b586fd3f6758ac18ef488c97169d1bd968124..ee7841bd5a6d9efcd4e9b3eacf2e76760407c7f3 100755 (executable)
@@ -104,4 +104,16 @@ ${CMD_PREFIX} ostree --repo=repo refs ctest --create=foo
 ${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create4
 assert_file_has_content refscount.create4 "^6$"
 
+#Check if a name for a ref in remote repo can be used locally, and vice versa.
+${CMD_PREFIX} ostree --repo=repo commit --branch=origin:remote1
+${CMD_PREFIX} ostree --repo=repo commit --branch=local1
+${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create5
+assert_file_has_content refscount.create5 "^8$"
+
+${CMD_PREFIX} ostree --repo=repo refs origin:remote1 --create=remote1
+${CMD_PREFIX} ostree --repo=repo refs origin:remote1 --create=origin/remote1
+${CMD_PREFIX} ostree --repo=repo refs local1 --create=origin:local1
+${CMD_PREFIX} ostree --repo=repo refs | wc -l > refscount.create6
+assert_file_has_content refscount.create6 "^11$"
+
 echo "ok refs"